Index: Modules/binascii.c =================================================================== --- Modules/binascii.c (revision 74244) +++ Modules/binascii.c (working copy) @@ -420,10 +420,14 @@ } } + /* Fail on non-base64-encoded character. */ this_ch = table_a2b_base64[*ascii_data]; - if ( this_ch == (unsigned char) -1 ) - continue; - + if ( this_ch == (unsigned char) -1 ) { + PyErr_SetString(PyExc_TypeError, "Non-base64 digit found"); + Py_DECREF(rv); + return NULL; + } + /* ** Shift it in on the low end, and see if there's ** a byte ready for output. Index: Lib/test/test_base64.py =================================================================== --- Lib/test/test_base64.py (revision 74244) +++ Lib/test/test_base64.py (working copy) @@ -137,7 +137,18 @@ self.assertRaises(TypeError, base64.urlsafe_b64decode, "") def test_b64decode_error(self): - self.assertRaises(binascii.Error, base64.b64decode, b'abc') + ar = self.assertRaises + ar(binascii.Error, base64.b64decode, b'abc') + # Test some invalid characters; addresses [1466065]. + ar(TypeError, base64.b64decode, b'%3d3LnB5dGhvbi5vcmc=') + ar(TypeError, base64.b64decode, b'$3d3LnB5dGhvbi5vcmc=') + ar(TypeError, base64.b64decode, b'[3d3LnB5dGhvbi5vcmc=') + ar(TypeError, base64.b64decode, b']3d3LnB5dGhvbi5vcmc=') + ar(TypeError, base64.b64decode, b'{3d3LnB5dGhvbi5vcmc=') + ar(TypeError, base64.b64decode, b'}3d3LnB5dGhvbi5vcmc=') + ar(TypeError, base64.b64decode, b'@3d3LnB5dGhvbi5vcmc=') + ar(TypeError, base64.b64decode, b'!3d3LnB5dGhvbi5vcmc=') + ar(TypeError, base64.b64decode, b'#3d3LnB5dGhvbi5vcmc=') def test_b32encode(self): eq = self.assertEqual